package com.dongdongshop.mq;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dongdongshop.pojo.SendOrder;
import com.dongdongshop.pojo.TbOrder;
import com.dongdongshop.pojo.TbOrderItem;
import com.dongdongshop.service.OrderService;
import com.dongdongshop.service.impl.OrderServiceImpl;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;

@RocketMQTransactionListener(txProducerGroup = "tx-group")
public class MQConsumerTransactionListener implements RocketMQLocalTransactionListener {


    @Autowired
    private OrderServiceImpl orderService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 1、MQ服务，成功接到事物消息后，执行本方法；
     * 2、处理本地事物，并将本地事物处理结果返回给MQ服务
     *
     * @return COMMIT, ROLLBACK, UNKNOWN;
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        try {
            //1.接收事务回调消息
            SendOrder sendOrder = (SendOrder) o;
            String out_trade_no = sendOrder.getOut_trade_no();
            TbOrder order = sendOrder.getOrder();
            TbOrderItem orderItem = sendOrder.getOrderItem();
            //2.执行本地事务
            orderService.payOrderSuccessfully(out_trade_no, order, orderItem);
        }catch (Exception e){   //处理异常 返回ROLLBACK
            e.printStackTrace();
            //redis备份 事务回查时使用
            redisTemplate.boundHashOps("tx").put(message.getHeaders().get("TRANSACTION_ID").toString(), "2");
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        //redis备份 事务回查时使用
        //redisTemplate.boundHashOps("tx").put(message.getHeaders().get("TRANSACTION_ID").toString(), "1");
        //处理正常 返回COMMIT
        return RocketMQLocalTransactionState.COMMIT;
    }

    /**
     * MQ服务 由于网络等原因 未收到 本地事物处理结果，回查本地事物处理结果
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        //通过事务id获取 redis中 对应的本地事务执行状态
        String status = (String) redisTemplate.boundHashOps("tx").get(message.getHeaders().get("TRANSACTION_ID").toString());
        if ("1".equals(status)) {   //已经执行过本地事务
            return RocketMQLocalTransactionState.COMMIT;
        } else if ("2".equals(status)) {    //没有执行过本地事务
            //继续处理，或者直接回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        } else {
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}
